<?php

namespace app\admin\controller;

use app\admin\model\Admin;
use app\admin\model\Menu;
use app\common\BaseHelper as Helper;
use app\common\Common;

use think\Cache;
use think\Request;
use think\Controller;
use think\exception\Handle;

class Base extends Controller
{

    protected $admin = ''; //Admin
    protected $menu = null; //Current Menu Obj
    protected $model = ''; //Model Name
    protected $exceptAction = []; // 不需要验证权限的action
    protected $accessAction = ['index', 'add']; // 需要验证权限的action
    protected $access = [];
    protected $indexView = 'list'; //Index View
    protected $addView = 'add'; //Add View
    protected $editView = 'edit'; //Edit View
    protected $defaultWhere = []; //default where
    protected $defaultOrder = '';
    protected $searchFields = []; //normal search
    protected $pageSize = ['20', '30', '50', '100', '200'];
    protected $primaryKey = 'id'; //primaryKey
    protected $view = '';
    protected $redirect = '';
    protected $topMenuId = '1'; // 当前菜单的最上级级菜单ID

    public function _initialize()
    {
        parent::_initialize();

        $module = $this->request->module();
        $controller = $this->request->controller();
        $action = $this->request->action();

        if(!in_array($this->request->action(), $this->accessAction)){
            $action = 'index';
        }else if(preg_match('/add/', $action) || preg_match('/edit/', $action)){
            $action = 'index';
        }
        // 获取当前菜单
        $this->menu = Menu::where('url', $module . '/' . $controller . '/' . $action)->find();

        // 获取当前model
        $this->model = $this->request->controller();
        $this->assign('model', $this->model);

        // check route auth
        $this->authCheck();

        $this->assign('admin', $this->admin);

        // 顶部菜单
        $this->assign('topMenu', $this->topMenuHtml($this->menuJson()));
        // 左侧菜单
        $this->assign('sidebar', $this->sidebarHtml($this->menuJson()));

        $this->assign('currentUrl', $this->request->url());
    }

    /**
     * Check route auth
     */
    private function authCheck()
    {
        $session_admin = session('ADMIN');
        
        if(!empty($session_admin->id)){
            $this->admin = $session_admin;

            if(!$this->checkAccess()){
                $this->error('您没有访问权限！');
            }
            $this->assign('adminInfo', $session_admin);
        }else{
            if($this->request->isAjax()){
                $this->error('您没有访问权限！', url('admin/auth/login'));
            }else{
                $this->redirect('admin/auth/login');
            }
        }
    }

    /**
     * 权限检查
     * @return bool
     */
    private function checkAccess() {
        /*if(in_array($this->request->action(), $this->exceptAction)){
            return true;
        }*/
        if(!in_array($this->request->action(), $this->accessAction)){
            return true;
        }
        // 0-超级管理员
        if($this->admin->type == 0) {
            return true;
        }

        $roleIds = explode(',', $this->admin->role_id);
        $roleAccess = \app\admin\model\Role::whereIn('id', $roleIds)->column('role_auth');
        //$roleAccessStr = implode(',', $roleAccess);
        //$access = array_unique(explode(',', $roleAccess));
        $this->access = $roleAccess;
        if(strtolower($this->request->controller()) != 'menu' && !$this->menu){
            $this->error('该页面不存在！');
        }

        // 首页 和 二级菜单页面 默认有权限
        if(in_array(strtolower($this->request->controller()), ['dashboard']) && $this->request->action() == 'index'){
            return true;
        }

        if(!in_array($this->menu->id, $this->access)){
            return false;
        }

        return true;
    }

    /**
     * Cache menu
     *
     * @param null $data
     * @return bool|null
     */
    public function menuCache($data = null) {
        if (empty($data)) {
            $data = Menu::getTree(0);
            // 缓存
            Cache::set('admin_menu', $data, 3600*6);
        } else {
            Cache::set('admin_menu', $data, 3600*6);
        }
        return $data;
    }

    /**
     * 菜单树状结构集合
     */
    public function menuJson() {
        $menu = Cache::get('admin_menu');
        if (!$menu) {
            $menu = $this->menuCache();
        }
        return $menu;
    }

    /**
     * 顶部菜单
     */
    public function topMenuHtml($menus) {
        if($menus){
            $pc = '';
            $mobile = '';

            foreach($menus as $menu){
                // 检查菜单权限
                if ($this->admin->type != '0' && !in_array($menu['id'], $this->access)) {
                    continue;
                }
                // 检测特殊权限  TODO

                $uri = $this->request->path();
                $uri_arr = explode('/', $uri);
                count($uri_arr) < 2 && $uri_arr[1] = 'index';
                if(count($uri_arr) < 3 || preg_match('/add/', $uri_arr[2]) || preg_match('/edit/', $uri_arr[2]) || (isset($uri_arr[3]) && $uri_arr[3] == 'id')){
                    $uri_arr[2] = 'index';
                }
                if(($uri_arr[0] == strtolower($menu['app']) && $uri_arr[1] == strtolower($menu['controller']) && $uri_arr[2] == strtolower($menu['action']))){
                    $active = 'layui-this';
                    $this->topMenuId = $menu['id'];
                }else{
                    $active = '';
                }

                $module = $this->request->module();
                $controller = $this->request->controller();
                //$action = $this->request->action();
                $action = 'index';
                $current = Menu::where(['url' => $module . '/' . $controller . '/' . $action])->find();
                $parentIds = $this->getParentIds($current['parent_id']);
                $parentIdsArr = explode(',' , $parentIds);
                if(in_array($menu['id'], $parentIdsArr)){
                    $active = 'layui-this';
                    $this->topMenuId = $menu['id'];
                }

                $pc .= '<li class="layui-nav-item '.$active.'">';
                $pc .= '<a href="'.$menu['url'].'">';
                $pc .= '<i class="layui-icon" data-icon="'.$menu['icon'].'">'.$menu['icon'].'</i><cite>'.$menu['name'].'</cite>';
                $pc .= '</a>';
                $pc .= '</li>';

                $mobile .= '<dd class="'.$active.'">';
                $mobile .= '<a href="'.$menu['url'].'">';
                $mobile .= '<i class="layui-icon" data-icon="'.$menu['icon'].'">'.$menu['icon'].'</i><cite>'.$menu['name'].'</cite>';
                $mobile .= '</a>';
                $mobile .= '</dd>';
            }

            return [
                'pc' => $pc,
                'mobile' => $mobile
            ];
        }
    }

    /**
     * 左侧菜单
     */
    public function sidebarHtml($menus) {
        if($menus){
            $menus = $menus[$this->topMenuId . 'Admin'];

            $childs = isset($menus['items']) ? $menus['items'] : [];
            $output = '';
            if($childs){
                foreach($childs as $menu){
                    // 检查菜单权限
                    if ($this->admin->type != '0' && !in_array($menu['id'], $this->access)) {
                        continue;
                    }

                    $uri = $this->request->path();
                    $uri_arr = explode('/', $uri);
                    count($uri_arr) < 2 && $uri_arr[1] = 'index';
                    if(count($uri_arr) < 3 || preg_match('/add/', $uri_arr[2]) || preg_match('/edit/', $uri_arr[2]) || (isset($uri_arr[3]) && $uri_arr[3] == 'id')){
                        $uri_arr[2] = 'index';
                    }
                    if(($uri_arr[0] == strtolower($menu['app']) && $uri_arr[1] == strtolower($menu['controller']) && $uri_arr[2] == strtolower($menu['action']))){
                        $active = 'layui-this';
                    }else{
                        $active = '';
                    }

                    $module = $this->request->module();
                    $controller = $this->request->controller();
                    //$action = $this->request->action();
                    $action = 'index';
                    $current = Menu::where(['url' => $module . '/' . $controller . '/' . $action])->find();
                    $parentIds = $this->getParentIds($current['parent_id']);
                    $parentIdsArr = explode(',' , $parentIds);
                    if(in_array($menu['id'], $parentIdsArr)){
                        $active = 'layui-this';
                    }

                    $output .= '<li class="layui-nav-item '.$active.'">';
                    $output .= '<a href="'.$menu['url'].'">';
                    if($menu['icon']){
                        $output .= '<i class="layui-icon" data-icon="'.$menu['icon'].'">'.$menu['icon'].'</i>';
                    }
                    $output .= '<cite>'.$menu['name'].'</cite>';
                    $output .= '</a>';
                    $output .= '</li>';
                }
            }

            return $output;
        }
    }

    // 得到父辈、爷辈、祖辈...的集合
    public function getParentIds($parentId, $level = 0) {
        $result = Menu::where(['id' => $parentId])->find();
        $parentIds = $result['id'];

        if($result['parent_id']){
            $level = $level + 1;
            $parentIds .= ',' . $this->getParentIds($result['parent_id'], $level);
        }
        return $parentIds;
    }

    /**
     * Show
     *
     * @param $template
     * @param array $data
     * @return mixed
     */
    private function show($template, $data = []) {

        return $this->view->fetch($template, $data);
    }

    /**
     * List
     */
    public function index(){
        $request = $this->request;
        $param = $request->param();
        // Reset filter
        if ($request->param('reset')) {
            return redirect(fullUrl($request->path()));
        }
        if($request->isAjax()){
            $model = model($this->model);

            // 每页起始条数
            $start = ($param['page'] - 1) * $param['limit'];
            // 每页显示条数
            $length = $param['limit'];
            // 排序条件
            $order = '';

            $where = $this->getFilterWhere($request);
            if($this->defaultWhere){
                $where = array_merge($this->defaultWhere, $where);
            }
            if($this->defaultOrder){
                $order = $this->defaultOrder;
            }

            $data = $model->where($where)->limit($start, $length)->order($order)->select();
            $count = $model->where($where)->count();

            if($data){
                // 处理列表数据
                $data = $this->handleListData($data);
            }

            $result = [
                'code' => '0',
                'msg' => '',
                'data' => $data,
                'count' => $count,
            ];

            return json($result);
        }

        return self::show($this->indexView, [
            'pageSize' => ['url' => fullUrl($request->path())],
            'searchFields' => $this->searchFields,
            'param' => $request->param()
        ]);
    }

    /**
     * Add
     */
    public function add(Request $request){

        return self::show($this->addView, []);
    }

    /**
     * Add Post
     */
    public function addPost(Request $request, $redirect){
        $model = model($this->model);

        if ($request->isPost()) {
            $data = $request->param();
            // Insert data
            $data['id'] = Helper::getUUID();
            $data['create_date'] = date('Y-m-d H:i:s');
            $data['create_oper'] = $this->admin->id;
            $result = $model->save($data);

            if($result !== false) {
                // Query执行后的操作
                $model->_after_insert($data);

                // 写入日志
                $logInfo = $this->admin->name . '添加了一条' . lang($this->model) . '数据。';
                Common::adminLog($request, $logInfo);

                if ($redirect) {
                    return $this->success('添加成功！', $redirect);
                } else {
                    return $this->success('添加成功！', 'admin/' . strtolower($this->model) . '/index');
                }
            } else {
                return $this->error($model->getError());
            }
        } else {
            return $this->error('提交方式错误！');
        }
    }

    /**
     * Edit
     */
    public function edit(Request $request){
        $model = model($this->model);
        $id = $request->param('id');
        // Get data info
        $info = $model->find($id);

        if(!$info){
            return $this->error('error !', 'admin/' . strtolower($this->model) . '/index');
        }

        return $this->show($this->editView, [
            'info' => $info
        ]);
    }

    /**
     * Edit Post
     */
    public function editPost(Request $request, $redirect){
        $model = model($this->model);

        if ($request->isPost()) {
            $data = $request->param();
            // Update data
            $data['update_date'] = date('Y-m-d H:i:s');
            $data['update_oper'] = $this->admin->id;
            $result = $model->allowField(true)->save($data, ['id' => $data['id']]);

            if($result !== false) {
                // Query执行后的操作
                $model->_after_update($data);

                // 写入日志
                $logInfo = $this->admin->name . '更新了一条' . lang($this->model) . '数据。';
                Common::adminLog($request, $logInfo);

                if ($redirect) {
                    return $this->success('编辑成功！', $redirect);
                } else {
                    return $this->success('编辑成功！', 'admin/' . strtolower($this->model) . '/index');
                }
            } else {
                return $this->error($model->getError());
            }
        } else {
            return $this->error('提交方式错误！');
        }
    }

    /**
     * Delete
     */
    public function delete(){
        $model = model($this->model);

        $request = $this->request;
        $id = $request->param('id');
        $param = $request->param();
        if (isset($_POST['ids'])) {
            // 删除多条
            $ids = $param['ids'];

            $result = $model->whereIn('id', $ids)->delete();

            if($result !== false){
                // Query执行后的操作
                $model->_after_delete($ids);

                $logInfo = $this->admin->name . '删除了' . count($ids) . '条' . lang($this->model) . '数据。';
                Common::adminLog($request, $logInfo);
            }
        } elseif($id) {
            // 删除一条
            $info = $model->find(['id', $id]);
            if(!$info){
                return redirect('admin/'.$this->model.'/index');
            }
            $result = $model->where('id', $id)->delete();

            if($result !== false){
                // Query执行后的操作
                $model->_after_delete($id);

                $logInfo = $this->admin->name . '删除了1条' . lang($this->model) . '数据。';
                Common::adminLog($request, $logInfo);
            }
        }

        if($result !== false){
            if(strtolower($request->controller()) != strtolower($this->model)){
                return $this->success('删除成功！', 'admin/' . strtolower($request->controller()) . '/index');
            }else{
                return $this->success('删除成功！', 'admin/' . strtolower($this->model) . '/index');
            }
        }else{
            return $this->error('删除失败！', 'admin/' . strtolower($this->model) . '/index');
        }
    }

    /**
     * 处理列表数据
     */
    public function handleListData($data){

        return $data;
    }

    /**
     * 筛选条件
     */
    public function getFilterWhere($request){
        $where = [];

        return $where;
    }

    /**
     * 默认条件
     */
    public function getDefaultWhere(){
        $defaultWhere = [];

        return $defaultWhere;
    }


}